﻿using ClosedXML.Excel;
using Microsoft.Win32;
using System.IO;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace ImageToExcel
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            this.loading.Visibility = Visibility.Hidden;
        }

        private void selectImageBtn_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Title = "选择图片";
            openFileDialog.Filter = "图片(*.png;*jpg;*jpge)|*.png;*.jpg;*.jpge";
            openFileDialog.Multiselect = false;

            if (openFileDialog.ShowDialog() != true)
            {
                return;
            }

            if (this.previewImage.Source != null && this.previewImage.Source is BitmapImage image)
            {
                image.Freeze();
            }

            var filePath = openFileDialog.FileName;

            var fs = new FileStream(filePath, FileMode.Open);

            BitmapImage bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.StreamSource = fs;
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.EndInit();

            fs.Close();
            fs.Dispose();

            this.previewImage.Source = bitmapImage;
        }

        private async void generateExcelBtn_Click(object sender, RoutedEventArgs e)
        {
            if (this.previewImage.Source == null && this.previewImage.Source is not BitmapImage)
            {
                MessageBox.Show("没有选择图片", "警告");
                return;
            }

            var saveFileDialog = new SaveFileDialog();
            saveFileDialog.Title = "保存文件";
            saveFileDialog.Filter = "Excel(*xlsx)|*.xlsx";
            saveFileDialog.AddExtension = true;
            saveFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            if (saveFileDialog.ShowDialog() != true)
            {
                return;
            }

            this.loading.Visibility = Visibility.Visible;

            var path = saveFileDialog.FileName;

            var image = this.previewImage.Source as BitmapImage;

            await GenerateExcel(image, path);

            MessageBox.Show("生成完毕。", "提示");
            this.loading.Visibility = Visibility.Hidden;
        }

        async Task GenerateExcel(BitmapImage image, string excelSavePath)
        {
            await Task.Yield();

            var workBook = new XLWorkbook();
            var sheet = workBook.AddWorksheet("图片");
            sheet.ColumnWidth = 1;
            sheet.RowHeight = 9;

            //最大约100列
            var stride = image.PixelWidth / 100;
            stride = Math.Max(stride, 1);

            for (int x = 0; x < image.PixelWidth; x += stride)
            {
                for (int y = 0; y < image.PixelHeight; y += stride)
                {
                    int totalR = 0;
                    int totalG = 0;
                    int totalB = 0;

                    for (int i = x; i < x + stride; i++)
                    {
                        for (int j = y; j < y + stride; j++)
                        {
                            var color = GetColor(ref image, i, j);
                            totalR += color.R;
                            totalG += color.G;
                            totalB += color.B;
                        }
                    }
                    var r = totalR / (stride * stride);
                    var g = totalG / (stride * stride);
                    var b = totalB / (stride * stride);

                    var xlColor = XLColor.FromArgb(r, g, b);

                    sheet.Cell(y / stride + 1, x / stride + 1).Style.Fill.BackgroundColor = xlColor;
                }
                await Task.Delay(1);
            }

            workBook.SaveAs(excelSavePath);
            workBook.Dispose();

        }

        Color GetColor(ref BitmapImage image, int x, int y)
        {
            var defaultColor = new Color();
            defaultColor.R = 255;
            defaultColor.G = 255;
            defaultColor.B = 255;

            if (x < 0 || x >= image.PixelWidth || y < 0 || y >= image.PixelHeight)
            {
                return defaultColor;
            }

            var bytesPerPixel = (image.Format.BitsPerPixel + 7) / 8;
            var pixelData = new byte[bytesPerPixel];

            var rect = new Int32Rect(x, y, 1, 1);

            image.CopyPixels(rect, pixelData, bytesPerPixel, 0);

            switch (image.Format.ToString())
            {
                case "Bgra32": // 最常见的格式（Blue, Green, Red, Alpha）
                    return Color.FromArgb(pixelData[3], pixelData[2], pixelData[1], pixelData[0]);

                case "Rgba32": // (Red, Green, Blue, Alpha)
                    return Color.FromArgb(pixelData[3], pixelData[0], pixelData[1], pixelData[2]);

                case "Rgb24": // (Red, Green, Blue) - 无 Alpha 通道
                    return Color.FromArgb(255, pixelData[0], pixelData[1], pixelData[2]);

                case "Bgr32": // (Blue, Green, Red) - 无 Alpha 通道
                    return Color.FromArgb(255, pixelData[2], pixelData[1], pixelData[0]);

                case "Pbgra32": // 预乘 Alpha 的 BGRA
                    byte a = pixelData[3];
                    byte r = (byte)((pixelData[2] * 255 + a / 2) / a);
                    byte g = (byte)((pixelData[1] * 255 + a / 2) / a);
                    byte b = (byte)((pixelData[0] * 255 + a / 2) / a);
                    return Color.FromArgb(a, r, g, b);

                default:
                    Console.WriteLine($"不支持的像素格式: {image.Format}");
                    break;
            }

            return defaultColor;
        }
    }
}